package com.community.process._1010.common.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.community.process._1010.common.api.CommonResult;
import com.community.process._1010.common.enums.BusinessTypeEnum;
import com.community.process._1010.config.ProcessOrderNotificationQueueConfig;
import com.community.process._1010.config.property.ProcessProperty;
import com.community.process._1010.dao.entity.ProcessTOrder;
import com.community.process._1010.dao.view.ProcessOrderView;
import com.community.process._1010.domains.ProcessingCouponTypeDTO;
import com.community.process._1010.domains.external.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
public class ExternalApiUtils {

    private static final String baseUrl = ProcessProperty.baseUrl;
    // 创建订单
    private static final String createOrderUrl = "/gruul-mall-order/order/createExternalOrder";
    // 创建支付信息
    private static final String orderPayUrl = "/gruul-mall-order/order/pay/externalOrderPay";
    // 通过订单号获取支付流水信息
    private static final String orderInfoUrl = "/gruul-mall-order/order/createExternalOrder/getTransactionInfo";
    // 查询订单支付状态
    private static final String queryOrderPayStatusUrl = "/gruul-mall-order/order/queryOrderPayStatus";
    // 测试支付成功的接收消息的接口
    private static final String simulateSendingMq2Url = "/gruul-mall-order/order/simulateSendingMq2";
    // 批量查询订单状态接口（一次最多查询500条记录）
    private static final String batchQueryOrderPayStatus = "/gruul-mall-order/order/batchQueryOrderPayStatus";
    // 获取用户信息
    private static final String getSecureUserInfoUrl = "/gruul-mall-uaa/uaa/auth/oauth/getSecureUserInfo";
    // 发起退款
    private static final String agreeRefundUrl = "/gruul-mall-afs/external/afs/order/agreeRefund";
    // 取消订单
    private static final String cancelOrder = "/gruul-mall-order/order/cancelOrder";
    // 超时订单更新入口
    private static final String overtimeOrder = "/gruul-mall-order/order/overtimeOrder";
    // 对账单
    private static final String sendOrderEvaluate = "/gruul-mall-order/order/sendOrderEvaluate";
    //获取加工金额
    private static final String couponProcessing = "/addon-coupon/coupon/processingApi";

    public static CommonResult<List<ProcessingDato>> getCouponProcessing(ProcessingCouponTypeDTO.ProcessingCouponTypeSearch dto) {
        Maps<String, String> headers = Maps.of("Client-Type", dto.getClientType())
                .ofSet("Shop-Id", dto.getShopId())
                .ofSet("Authorization", dto.getToken())
                .ofSet("Platform", dto.getPlatform());

        String resultBody = HttpUtils.get(baseUrl + couponProcessing,null,headers,-1);
        ExternalResult<ProcessingDato> result;
        try {
            result = JSON.parseObject(resultBody, new TypeReference<>() {
            });
        } catch (Exception e) {
            return CommonResult.failed("获取加工金额信息异常");
        }
        if (result != null) {
            if (result.getCode() == 200) {
                return CommonResult.success(Collections.singletonList(result.getData()));
            }
            return CommonResult.failed(result.getCode(), result.getMsg());
        }
        return CommonResult.failed("获取加工金额信息异常");
    }

    public static CommonResult<List<ProcessingDato>> getCouponMioiProcessing(ProcessingCouponTypeDTO.ProcessingCouponTypeSearch dto) {
        Maps<String, String> headers = Maps.of("Client-Type", dto.getClientType())
                .ofSet("Shop-Id", Optional.ofNullable(dto.getShopId()).orElse("0"))
                .ofSet("Authorization", dto.getToken())
                .ofSet("Platform", dto.getPlatform());

        String resultBody = HttpUtils.get(baseUrl + couponProcessing,null,headers,-1);
        ExternalResult<ProcessingDato> result;
        try {
            result = JSON.parseObject(resultBody, new TypeReference<>() {
            });
        } catch (Exception e) {
            return CommonResult.failed("获取加工金额信息异常");
        }
        if (result != null) {
            if (result.getCode() == 200) {
                return CommonResult.success(Collections.singletonList(result.getData()));
            }
            return CommonResult.failed(result.getCode(), result.getMsg());
        }
        return CommonResult.failed("获取加工金额信息异常");
    }

    public static CommonResult<ExternalUserData> getSecureUserInfo(ExternalTokenLoginDTO dto) {
        Maps<String, String> headers = Maps.of("Client-Type", dto.getClientType())
                .ofSet("Shop-Id", dto.getShopId())
                .ofSet("Authorization", dto.getToken())
                .ofSet("Platform", dto.getPlatform());
        String resultBody = HttpUtils.get(baseUrl + getSecureUserInfoUrl,null,headers,-1);
        ExternalResult<ExternalUserData> result;
        try {
            result = JSON.parseObject(resultBody, new TypeReference<>() {
            });
        } catch (Exception e) {
            return CommonResult.failed("token获取用户信息异常");
        }
        if (result != null) {
            if (result.getCode() == 200) {
                return CommonResult.success(result.getData());
            }
            return CommonResult.failed(result.getCode(), result.getMsg());
        }
        return CommonResult.failed("token获取用户信息异常");
    }

    /**
     * @param outTradeNo       订单号
     * @param orderAmount      订单金额
     * @param freightPrice     运费
     * @param couponIds        优惠券ID
     * @param processTOrder    订单信息
     * @param subProcessOrders
     * @param dto              TOKEN
     * @return CreateExternalOrderData
     */
    public static CommonResult<CreateExternalOrderData> createOrder(String outTradeNo, Long orderAmount, Long freightPrice, List<Long> couponIds, ProcessTOrder processTOrder, List<ProcessOrderView> subProcessOrders, ExternalTokenLoginDTO dto) {
        Maps<String, String> headers = Maps.of("Client-Type", dto.getClientType())
                .ofSet("Shop-Id", dto.getShopId())
                .ofSet("Authorization", dto.getToken())
                .ofSet("Platform", dto.getPlatform());
        // 转换单位 分 -》 元
        BigDecimal totalAmount = new BigDecimal(orderAmount).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
        BigDecimal carriage = new BigDecimal(freightPrice).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
        List<Maps<String, Object>> sellerOrderList = createSellerOrderList(subProcessOrders);
        Maps<String, Object> params = Maps.ofObj("orderNo", outTradeNo)
                .ofSet("orderAmount", totalAmount)
                .ofSet("subscribeToATopic", ProcessOrderNotificationQueueConfig.ROUTING_KEY)
                .ofSet("carriage", carriage)
                .ofSet("couponIds", CollectionUtils.isEmpty(couponIds) ?  new ArrayList<>() : couponIds)
                .ofSet("businessType", BusinessTypeEnum.EXTERNAL_MEAL_PROCESSING.getCode())
                .ofSet("miniAppDeliver", true)
                .ofSet("shopId", dto.getShopId())
                .ofSet("sellerOrderList",sellerOrderList)
                .ofSet("itemJson", Maps.ofObj("items", Collections.singletonList(Maps.ofObj("productName", processTOrder.getItemName()).ofSet("productCount", 1))));
        log.info("请求头：{}，请求参数：{}", JSON.toJSONString(headers), JSON.toJSONString(params));
        String resultBody = HttpUtils.postToJson(baseUrl + createOrderUrl, params, headers, -1);
        ExternalResult<CreateExternalOrderData> result;
        try {
            result = JSON.parseObject(resultBody, new TypeReference<>() {
            });
        } catch (Exception e) {
            return CommonResult.failed("创建订单异常");
        }
        if (result != null) {
            if (result.getCode() == 200) {
                return CommonResult.success(result.getData());
            }
            return CommonResult.failed(result.getCode(), result.getMsg());
        }
        return CommonResult.failed("创建订单异常");
    }

    private static List<Maps<String, Object>> createSellerOrderList(List<ProcessOrderView> subProcessOrders) {
        return subProcessOrders.stream().map(item -> {
            List<Maps<String, Object>> collect = item.getOrdersItems().stream().map(ordersItem -> Maps.ofObj("itemId", ordersItem.getItemId())
                    .ofSet("itemName", ordersItem.getItemName())
                    .ofSet("itemImage", ordersItem.getImage())
                    .ofSet("itemNum", ordersItem.getItemNum())
                    .ofSet("itemPrice", ordersItem.getItemPrice())
                    .ofSet("totalPrice", ordersItem.getTotalPrice())
                    .ofSet("weight", 1)).collect(Collectors.toList());

            return Maps.ofObj("subOrderNo", "dcs"+item.getId())
                    .ofSet("sellerId",0)
                    .ofSet("sellerType",0)
                    .ofSet("orderAmount",item.getPayAmount())
                    .ofSet("carriage",0)
                    .ofSet("orderItemList", collect)
            ;
        }).collect(Collectors.toList());

    }



    /**
     * 同意退款
     * @param outTradeNo 订单号
     * @param dto 请求参数
     * @return
     */
    public static CommonResult<Boolean> agreeRefundUrl(String outTradeNo, ExternalTokenLoginDTO dto) {
        Maps<String, String> headers = Maps.of("Client-Type", dto.getClientType())
                .ofSet("Shop-Id", dto.getShopId())
                .ofSet("Authorization", dto.getToken())
                .ofSet("Platform", dto.getPlatform());


        String resultBody = HttpUtils.put(baseUrl + agreeRefundUrl + "/" + outTradeNo, null, headers, -1);
        ExternalResult<Boolean> result;
        try {
            result = JSON.parseObject(resultBody, new TypeReference<>() {
            });
        } catch (Exception e) {
            return CommonResult.failed("同意退款异常："+ resultBody);
        }
        if (result != null) {
            if (result.getCode() == 200 && result.getData() != null && result.getData() && result.getSuccess()) {
                return CommonResult.success(true);
            }
            return CommonResult.failed(result.getCode(), result.getMsg() + ":" + resultBody);
        }
        return CommonResult.failed("同意退款异常："+ resultBody);
    }

    /**
     * 发送订单评价
     * @param outTradeNo 订单号
     * @param dto  TOKEN
     * @return CommonResult<Boolean>
     */
    public static CommonResult<Boolean> sendOrderEvaluate(String outTradeNo) {
        String resultBody = HttpUtils.post(baseUrl + sendOrderEvaluate + "/" + outTradeNo, null, null, -1);
        ExternalResult<Boolean> result;
        try {
            result = JSON.parseObject(resultBody, new TypeReference<>() {
            });
        } catch (Exception e) {
            return CommonResult.failed("同意退款异常："+ resultBody);
        }
        if (result != null) {
            if (result.getCode() == 200 && result.getData() != null && result.getData() && result.getSuccess()) {
                return CommonResult.success(true);
            }
            return CommonResult.failed(result.getCode(), result.getMsg() + ":" + resultBody);
        }
        return CommonResult.failed("同意退款异常："+ resultBody);
    }
    /**
     * 取消订单
     * @param outTradeNo 订单号
     * @param dto 请求参数
     * @return
     */
    public static CommonResult<String> cancelOrder(String outTradeNo, ExternalTokenLoginDTO dto) {
        Maps<String, String> headers = Maps.of("Client-Type", dto.getClientType())
                .ofSet("Shop-Id", dto.getShopId())
                .ofSet("Authorization", dto.getToken())
                .ofSet("Platform", dto.getPlatform());


        String resultBody = HttpUtils.get(baseUrl + cancelOrder + "/" + outTradeNo, null, headers, -1);
        ExternalResult<String> result;
        try {
            result = JSON.parseObject(resultBody, new TypeReference<>() {
            });
        } catch (Exception e) {
            return CommonResult.failed("取消订单异常");
        }
        if (result != null) {
            if (result.getCode() == 200 && result.getSuccess()) {
                return CommonResult.success(result.getData() == null ? "" : result.getData());
            }
            return CommonResult.failed(result.getCode(), result.getMsg());
        }
        return CommonResult.failed("取消订单异常");
    }

    /**
     * 超时订单更新入口
     * @param outTradeNo 订单号
     * @return String
     */
    public static CommonResult<String> overtimeOrder(String outTradeNo) {
        Maps<String, String> headers = Maps.of("Client-Type", "CONSUMER")
                .ofSet("Shop-Id", "0")
                .ofSet("Platform", "WECHAT_MINI_APP");

        String resultBody = HttpUtils.post(baseUrl + overtimeOrder + "/" + outTradeNo, null, headers, -1);
        ExternalResult<String> result;
        try {
            result = JSON.parseObject(resultBody, new TypeReference<>() {
            });
        } catch (Exception e) {
            return CommonResult.failed("超时订单更新异常");
        }
        if (result != null) {
            if (result.getCode() == 200 && result.getSuccess()) {
                return CommonResult.success(result.getData() == null ? "" : result.getData());
            }
            return CommonResult.failed(result.getCode(), result.getMsg());
        }
        return CommonResult.failed("超时订单更新异常");
    }
}
